<?php
/**
 * Created by PhpStorm.
 * User: kwibon
 * Date: 2018/11/26
 * Time: 11:18
 */
namespace app\api\controller;

libxml_disable_entity_loader(false);

use app\common\controller\Api;
use app\api\model\Tacity;
use app\api\model\Tahotel;
use app\admin\model\GeoHash;

class TeamAmericany extends Api
{
    private $UserName = 'XMLKUACN';
    private $Password = 'xAVAOgH9';
    private $wsdlUrl = 'https://developers.teamamericany.com/taxml/services/tadoclit?wsdl';


    public function writeLog($msg){//记录日志   by Suley
        if(!$msg) return false;
        $dir = '/var/www/html/log';
        $log = 'ta_log';
        $filesize = filesize($dir.'/'.$log);
        if($filesize>3145728){//设置log文件大小为3mb
            rename($dir.'/'.$log,$dir.'/'.$log."".date('YmdH',time()));
        }
        $result = file_put_contents($dir.'/'.$log,(date('Y-m-d h:i:s',time())).'   '.$msg."\r\n",FILE_APPEND);
        return $result;
    }


    //实例化soapClient
    public function getSoapClient($url){
        try {
            $client = new \SoapClient($url);
            return $client;
        } catch (\SOAPFault $e) {
            return false;
        }
    }

    //获取WSDL方法名
    public function getFunctions(){
        $SoapClient = $this->getSoapClient($this->wsdlUrl);
        $functionArr = $SoapClient->__getFunctions();

        echo "<pre>";
        var_dump($functionArr);
        echo "</pre>";
        exit;
    }

    //获取WSDL方法参数详情
    public function getFunDetails(){
        $SoapClient = $this->getSoapClient($this->wsdlUrl);
        $type = $SoapClient->__getTypes();

        echo "<pre>";
        var_dump($type);
        echo "</pre>";
        exit;
    }

    //ListCities
    public function ListCities(){
        ignore_user_abort();//关闭浏览器仍然执行
        set_time_limit(0);//让程序一直执行下去
        $data = [];
        $data['UserName'] = $this->UserName;
        $data['Password'] = $this->Password;

        $SoapClient = $this->getSoapClient($this->wsdlUrl);
        $res = $SoapClient->__soapCall("ListCities",[$data]);
        $res = json_decode(json_encode($res),true);

        return $res;
    }

    //ListRoomType
    public function ListRoomType(){
        ignore_user_abort();//关闭浏览器仍然执行
        set_time_limit(0);//让程序一直执行下去
        $data = [];
        $data['UserName'] = $this->UserName;
        $data['Password'] = $this->Password;

        $SoapClient = $this->getSoapClient($this->wsdlUrl);
        $res = $SoapClient->__soapCall("ListRoomType",[$data]);

        $res = json_decode(json_encode($res),true);

        echo "<pre>";
        var_dump($res);
        echo "</pre>";
        exit;
    }

    //ListVendor
    public function ListVendor($CityCode="NYC"){
        ignore_user_abort();//关闭浏览器仍然执行
        set_time_limit(0);//让程序一直执行下去
        $data = [];
        $data['UserName'] = $this->UserName;
        $data['Password'] = $this->Password;
        $data['CityCode'] = $CityCode;
        $data['Type'] = "Hotel";//Hotel & Service可选

        $SoapClient = $this->getSoapClient($this->wsdlUrl);
        $res = $SoapClient->__soapCall("ListVendor",[$data]);

        $res = json_decode(json_encode($res),true);
        return $res;
    }

    //ProductInfo
    public function ProductInfo($VendorID=0){
        ignore_user_abort();//关闭浏览器仍然执行
        set_time_limit(0);//让程序一直执行下去
        if(empty($VendorID)) return [];
        $data = [];
        $data['UserName'] = $this->UserName;
        $data['Password'] = $this->Password;
        $data['VendorID'] = (int)$VendorID;

        try {
            $SoapClient = $this->getSoapClient($this->wsdlUrl);
            $res = $SoapClient->__soapCall("ProductInfo",[$data]);
            $res = json_decode(json_encode($res),true);
        }catch (\Exception $exception){
            $res = [];
        }
        return $res;
    }

    //PriceSearch
    public function PriceSearch($CityCode,$VendorID,$ArrivalDate,$Occupancy='Single',$NumberOfNights=1,$NumberOfRooms=1){
        ignore_user_abort();//关闭浏览器仍然执行
        set_time_limit(0);//让程序一直执行下去
        $data = [];
        $data['UserName'] = $this->UserName;
        $data['Password'] = $this->Password;
        $data['CityCode'] = $CityCode;
        $data['ProductCode'] = '';
        $data['Type'] = 'Hotel';
        $data['Occupancy'] = $Occupancy;//Single, Double, Triple, Quad, SGL+1CH, DBL+1CH, DBL+2CH, TPL+1CH
        $data['ArrivalDate'] = $ArrivalDate;
        $data['NumberOfNights'] = $NumberOfNights;
        $data['NumberOfRooms'] = $NumberOfRooms;
        $data['DisplayClosedOut'] = 'Y';
        $data['DisplayOnRequest'] = 'Y';
        //选填
        $data['VendorIDs'] = ['VendorID'=>$VendorID];

        try {
            $SoapClient = $this->getSoapClient($this->wsdlUrl);
            $res = $SoapClient->__soapCall("PriceSearch",[$data]);

            $res = json_decode(json_encode($res),true);
        }catch (\Exception $exception){
            $res = [];
        }

        return $res;
    }

    //****************************************************************************************************
    //**************************操作接口方法**************************************************************

    //更新数据库中tacity表
    public function updateCities(){
        ignore_user_abort();//关闭浏览器仍然执行
        set_time_limit(0);//让程序一直执行下去

        $res = $this->ListCities();

        $Tacity = new Tacity();
        $oldTacity = db("tacity")->field("CityCode")->select();
        $oldCityArr = array_column($oldTacity,"CityCode");

        $cityArr = [];
        foreach ($res['cityResp']['body'] as $k=>$v) {
            if($v['Country']=='USA' || $v['Country']=='CANADA'){
                if(in_array($v['CityCode'],$oldCityArr)){
                    continue;
                }
                $cityArr[] = $v;
            }
        }

        $insertRes = $Tacity->insertAll($cityArr);

        if($insertRes){
            echo "新增".$insertRes."个城市";
        }else{
            echo "无新增城市";
        }

        exit;
    }

    //更新数据库中tahotel表
    public function updateHotels(){
        ignore_user_abort();//关闭浏览器仍然执行
        set_time_limit(0);//让程序一直执行下去
        ob_end_flush();//关闭缓存
        ob_implicit_flush(true);//每次缓存即时输出相当于每次输出后调用flush()
        header('X-Accel-Buffering: no');

        $tacityData = db("tacity")->field("CityCode")->select();
        $cityArr = array_column($tacityData,"CityCode");

        $Tahotel = new Tahotel();
        $tahotelData = db("tahotel")->field("VendorID")->select();
        if(!empty($tahotelData)){
            $vendorArr = array_column($tahotelData,"VendorID");
        }else{
            $vendorArr = [];
        }

        echo "【更新酒店，脚本执行开始】";

        foreach ($cityArr as $key=>$value) {
            $hotelArr = [];
            $vendor = $this->ListVendor($value);
            if(!empty($vendor['vendorResponse']['body'])){
                if(isset($vendor['vendorResponse']['body']['VendorID'])){//为单个数据时
                    $body = $vendor['vendorResponse']['body'];
                    if(!isset($body['VendorID']) || in_array($body['VendorID'],$vendorArr)){
                        continue;
                    }
                    $hotelArr[] = [
                        'VendorID'=>$body['VendorID'],
                        'CityCode'=>$value,
                        'VendorName'=>$body['VendorName'],
                        'City'=>$body['City'],
                    ];
                }else{
                    foreach ($vendor['vendorResponse']['body'] as $k=>$v) {
                        if(!isset($v['VendorID']) || in_array($v['VendorID'],$vendorArr)){
                            continue;
                        }

                        $hotelArr[] = [
                            'VendorID'=>$v['VendorID'],
                            'CityCode'=>$value,
                            'VendorName'=>$v['VendorName'],
                            'City'=>$v['City'],
                        ];
                    }
                }
            }

            $insertRes = $Tahotel->insertAll($hotelArr);

            if($insertRes){
                echo $value."城市新增".$insertRes."个酒店<br>";
            }else{
                echo $value."城市无新增酒店<br>";
            }
        }

        echo "【更新酒店，脚本执行完毕】";

        exit;
    }

    //更新hotel详情缓存
    public function saveHotelDetails(){
        ignore_user_abort();//关闭浏览器仍然执行
        set_time_limit(0);//让程序一直执行下去
//        ob_end_flush();//关闭缓存
//        ob_implicit_flush(true);//每次缓存即时输出相当于每次输出后调用flush()
//        header('X-Accel-Buffering: no');

        $time = strtotime(date('Y-m-d 00:00:00'));
        $where['updatetime'] = ['LT',$time];

        $tahotelData = db("tahotel")
            ->where($where)
            ->field("VendorID,CityCode")
//            ->limit(5)
            ->select();

        $this->writeLog("【酒店产品信息缓存，脚本执行开始，共".count($tahotelData)."个酒店】");

        $GeoHash = new GeoHash();

        try {
            foreach ($tahotelData as $key=>$value) {
                //*********检测脚本停止flag*****************
                $shflag = db("shflag")->where("id",1)->find();
                $flag = $shflag['flag'];
                if($flag==1){
                    $this->writeLog("【检测脚本停止flag，执行结束】");
                    exit;
                }

                $productData = $this->ProductInfo($value['VendorID']);
                if(!empty($productData['response']['body'])){
                    $detail = $productData['response']['body'];

                    if(isset($detail['ProductCode'])){//只有一个产品时
                        $detail = [0=>$detail];
                    }

                    cache($value['VendorID']."HotelDetail",$detail);

                    //缓存最低价格
                    $this->cachePrice($value['CityCode'],$value['VendorID']);

                    $list = [];
                    $list['HotelRating'] = $detail[0]['HotelRating'];
                    $list['Latitude'] = $detail[0]['Latitude'];
                    $list['Longitude'] = $detail[0]['Longitude'];
                    $list['VendorImage'] = !empty($detail[0]['VendorImage']) ? $detail[0]['VendorImage'] : '';
                    $list['VendorDescription'] = $detail[0]['VendorDescription'];
                    $list['VendorAddress'] = $detail[0]['VendorAddress1'];
                    $list['WebPriority'] = $detail[0]['WebPriority'];
                    $list['updatetime'] = time();

                    if(!empty($detail[0]['Latitude']) && !empty($detail[0]['Longitude'])){
                        $list['geoCode'] = $GeoHash->encode($detail[0]['Latitude'],$detail[0]['Longitude']);
                    }

                    db("tahotel")->where('VendorID',$value['VendorID'])->update($list);

                    $this->writeLog("【".$value['VendorID']."酒店缓存完毕】");
                }
            }
        }catch (\Exception $exception){
            $this->writeLog("【报错ERROR：】".$exception->getMessage());
            exit;
        }

        $this->writeLog("【酒店产品信息缓存完毕，脚本执行结束】");

        exit;
    }

    //价格缓存
    public function cachePrice($CityCode='NYC',$VendorID='61'){
        $ArrivalDate = date("Y-m-d");
        $datesPriceArr = [];
        for ($i=0;$i<5;$i++){
            $price = $this->PriceSearch($CityCode,$VendorID,$ArrivalDate,$Occupancy='Single',$NumberOfNights=20,$NumberOfRooms=1);
            if(empty($price['hotelSearchResponse']['body'])){
                continue;
            }
            if(isset($price['hotelSearchResponse']['body']['WebPriority'])){
                $priceArr[] = $price['hotelSearchResponse']['body'];
            }else{
                $priceArr = $price['hotelSearchResponse']['body'];
            }

            foreach ($priceArr as $key=>$value) {
                $NightlyInfo = $value['NightlyInfo'];
                foreach ($NightlyInfo as $k=>$v) {
                    if(!isset($datesPriceArr[$v['Dates']]) || $datesPriceArr[$v['Dates']]>$v['Prices']['AdultPrice']){
                        $datesPriceArr[$v['Dates']] = $v['Prices']['AdultPrice'];
                    }
                }
            }
            $num = 20*($i+1);
            $ArrivalDate = date('Y-m-d', strtotime('+'.$num.' days'));
        }
        //缓存最低价格集合
        cache($VendorID."datesPrice",$datesPriceArr);
        return true;

    }


    public function index(){
        $CityCode = 'ANA';
        $VendorID = '633';
        $ArrivalDate = '2020-12-01';
        $data = $this->PriceSearch($CityCode,[],$ArrivalDate,$Occupancy='',$NumberOfNights=5,$NumberOfRooms=1);
        dump($data);

    }

}